(*---------------------------------------------------------------------------
    :Program.    TrackDiskSupport
    :Author.     Fridtjof Siebert
    :Address.    Nobileweg 67, D-7-Stgt-40
    :Phone.      (0)711/822509
    :Shortcut.   [fbs]
    :Version.    .9
    :Date.       05-Dez-88
    :Copyright.  PD, no commercial use !!!
    :Language.   Modula-II
    :Translator. M2Amiga
    :Contents.   Procedures to simplify usage of the trackdisc.device
    :Remark.     You are NOT allowed to use this to write a Virus !!!
---------------------------------------------------------------------------*)

DEFINITION MODULE TrackDiskSupport;

FROM SYSTEM      IMPORT ADDRESS;

FROM Exec        IMPORT Byte;

(*------  Open TrackDisk:  ------*)

PROCEDURE OpenTrackDisk(device: INTEGER; AllowNon35: BOOLEAN): Byte;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Input.    AllowNon35: Allow non 3.5" drives (usually 5.25" drives)     *)
(* :Result.   Error number or 0 if successfully                            *)
(* :Semantic. Opens the Trackdisk.device for drive # device. It can be     *)
(* :Semantic. several times with different drive numbers.                  *)
(* :Note.     Don't forget CloseTrackDisk()!                               *)

(*------  Close TrackDisk:  ------*)

PROCEDURE CloseTrackDisk(device: INTEGER);

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Semantic. Closes the TrackDisk.device open via OpenTrackDisk()         *)

(*------  Get Disk Change Value:  ------*)

PROCEDURE GetDiskChange(device: INTEGER): LONGCARD;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Result.   Disk Change number (necessary to detect disk changes)        *)

(*------  Is there a disk inserted?  ------*)

PROCEDURE ChangeState(device: INTEGER): BOOLEAN;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Result.   TRUE if disk inserted, else FALSE                            *)



(*------  Test Write-Protection:  ------*)

PROCEDURE ProtStatus(device: INTEGER): BOOLEAN;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Result.   TRUE if write enabled                                        *)

(*------  Motor Control:  ------*)

PROCEDURE Motor(device: INTEGER; On: BOOLEAN): BOOLEAN;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Input.    On: turm Motor on (TRUE) or off (FALSE)                      *)
(* :Result.   old motor state: TRUE = on, FALSE = off                      *)
(* :Semantic. Turns motor on or off according to On.                       *)

(*------  Seek:  ------*)

PROCEDURE Seek(device: INTEGER; Offset: LONGCARD): Byte;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Input.    Offset: where to seek to. Must be a multiple of              *)
(* :Input.            numHeads * numSecs * sectors (2*11*512)              *)
(* :Semantic. Moves head to specified track                                *)

(*------  Read Block:  ------*)

PROCEDURE ReadBlock(device: INTEGER;
                    Block: INTEGER;
                    Buffer: ADDRESS;
                    BlockCnt: CARDINAL;
                    ChangeCnt: LONGCARD): Byte;

(* :Input.    device:   Drive Number (0..3)                                *)
(* :Input.    Block:    the disk's block # to be read                      *)
(* :Input.    Buffer:   at least 512 Bytes of Chip memory to store data    *)
(* :Input.    BlockCnt: Number of Blocks to be read                        *)
(* :Input.    ChangeCnt:last changenumber to check diskchanges             *)
(* :Result.   error number or 0 if none                                    *)
(* :Semantic. Reads BlockCnt Blocks from Disk                              *)

(*------  Read Sector:  ------*)

PROCEDURE ReadCycSec(device: INTEGER;
                     cyl,sec,head: INTEGER;
                     Buffer: ADDRESS;
                     BlockCnt: CARDINAL;
                     ChangeCnt: LONGCARD): Byte;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Input.    cyl,sec,head: specify the block to be read                   *)
(* :Input.    Buffer:       512 Bytes of Chip memory to store data         *)
(* :Input.    BlockCnt:     Number of Blocks to be read                    *)
(* :Input.    ChangeCnt:    last changenumber to check diskchanges         *)
(* :Result.   error number                                                 *)
(* :Semantic. Reads BlockCnt blocks                                        *)

(*------  Write Block:  ------*)

PROCEDURE WriteBlock(device: INTEGER;
                     block: INTEGER;
                     Buffer: ADDRESS;
                     BlockCnt: CARDINAL;
                     ChangeCnt: LONGCARD): Byte;

(* :Input.    device:    Drive Number (0..3)                               *)
(* :Input.    block:     the block # to be written                         *)
(* :Input.    Buffer:    512 Bytes of Chip memory storing the data         *)
(* :Input.    BlockCnt:  # of blocks to be written                         *)
(* :Input.    ChangeCnt: last changenumber to check diskchanges            *)
(* :Result.   error number                                                 *)
(* :Semantic. Writes BlockCnt blocks                                       *)

(*------  Write Sector:  ------*)

PROCEDURE WriteCycSec(device: INTEGER;
                      cyl,sec,head: INTEGER;
                      Buffer: ADDRESS;
                      BlockCnt: CARDINAL;
                      ChangeCnt: LONGCARD): Byte;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Input.    cyl,sec,head: specify the block to be written                *)
(* :Input.    Buffer:       512 Bytes of Chip memory storing the data      *)
(* :Input.    BlockCnt:     # of blocks to be written                      *)
(* :Input.    ChangeCnt:    last changenumber to check diskchanges         *)
(* :Result.   error number                                                 *)
(* :Semantic. Writes BlockCnt blocks                                       *)

(*------  Update:  ------*)

PROCEDURE Update(device: INTEGER;
                 ChangeCnt: LONGCARD): Byte;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Input.    ChangeCnt: last changenumber to check diskchanges            *)
(* :Result.   error                                                        *)
(* :Semantic. Forces to write buffer to disk                               *)

(*------  Format:  ------*)

PROCEDURE FormatTrack(device: INTEGER;
                      cyl: INTEGER;
                      Buffer: ADDRESS;
                      CycCnt: CARDINAL;
                      ChangeCnt: LONGCARD): Byte;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Input.    cyl:       First Cyclinder to be formatted                   *)
(* :Input.    Buffer:    Buffer containing cyclinder data (>= 22*512 Bytes)*)
(* :Input.    CycCnt:    Number of Tracks to be formatted                  *)
(* :Input.    ChangeCnt: last changenumber to check diskchanges            *)
(* :Result.   error number                                                 *)
(* :Semantic. Writes track to unformatted disk                             *)

(*------  Create Diskremove-Interrupt:  ------*)

PROCEDURE Remove(device: INTEGER;
                 IntProc: ADDRESS): Byte;

(* :Input.   device: Drive Number (0..3)                                   *)
(* :Input.   IntProc: The Interrupt Procedure's address or NIL to remove it*)
(* :Result.  error #                                                       *)
(* :Semantic.Adds / Removes interrupt to handle diskchanges                *)
(* :Note.    I was too lazy to test this ;-)                               *)

(*------  Mark Track as invalid:  ------*)

PROCEDURE Clear(device: INTEGER): Byte;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Result.   error or 0                                                   *)
(* :Semantic. Marks trackbuffer as invalid --> avoids rewriting it         *)

(*------  3.5 or 5.25 Drive:  ------*)

PROCEDURE GetDriveType(device: INTEGER): LONGCARD;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Result.   1 if 3.5 inch drive connected, else ??? (5.25")              *)
(* :Note.     I Couldn't test this (I don't have a 5.25" Drive)            *)

(*------  How many Trax:  ------*)

PROCEDURE GetNumTracks(device: INTEGER): LONGCARD;

(* :Input.    device: Drive Number (0..3)                                  *)
(* :Result.   number of tracks the drive has                               *)


END TrackDiskSupport.
